package org.jetlinks.demo.protocol.siterwell.tcp;

import io.netty.buffer.ByteBuf;
import io.netty.buffer.ByteBufUtil;
import lombok.AllArgsConstructor;
import lombok.SneakyThrows;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.codec.binary.Hex;
import org.jetlinks.core.device.DeviceRegistry;
import org.jetlinks.core.message.DeviceMessage;
import org.jetlinks.core.message.Message;
import org.jetlinks.core.message.codec.*;
import org.jetlinks.core.server.session.DeviceSession;
import org.reactivestreams.Publisher;
import reactor.core.publisher.Mono;

@AllArgsConstructor
@Slf4j
public class SiterWellTcpMessageCodec extends TcpMessageHandler implements DeviceMessageCodec {

    private DeviceRegistry registry;

    @Override
    public Transport getSupportTransport() {
        return DefaultTransport.TCP;
    }

    @Override
    @SneakyThrows
    public Mono<DeviceMessage> decode(MessageDecodeContext context) {
        log.debug("收到消息：");
        return Mono.defer(() -> {
            FromDeviceMessageContext ctx = ((FromDeviceMessageContext) context);
            ByteBuf byteBuf = context.getMessage().getPayload();
            byte[] payload = ByteBufUtil.getBytes(byteBuf, 0, byteBuf.readableBytes(), false);
            if (log.isDebugEnabled()) {
                log.debug("handle tcp message:\n{}", Hex.encodeHexString(payload));
            }

            DeviceSession session = ctx.getSession();
            SiterWellTcpMessage siterWellTcpMessage = SiterWellTcpMessage.of(payload);
            org.jetlinks.demo.protocol.siterwell.tcp.MessageType messageType = siterWellTcpMessage.getType();
            TcpPayload tcpPayload = siterWellTcpMessage.getData();

            return dealRequest(session, messageType, tcpPayload);
//            if (messageType.equals(org.jetlinks.demo.protocol.siterwell.tcp.MessageType.AUTH_REQ)) {
//                String payloadHex = Hex.encodeHexString(payload);
//                String deviceId = getGatewayId(payloadHex);
//                DeviceOnlineMessage onlineMessage = new DeviceOnlineMessage();
//                onlineMessage.setDeviceId(deviceId);
//                onlineMessage.setTimestamp(System.currentTimeMillis());
//                byte[] responseBytes = S2DAuthResponse.of((D2SAuthRequest) tcpPayload).toBytes();
//                return session
//                        .send(EncodedMessage.simple(Unpooled.wrappedBuffer(responseBytes)))
//                        .doOnNext(success -> {
//                            if (log.isDebugEnabled()) {
//                                log.debug("reply tcp message:\n{}", ByteUtils.byte2HexStr(responseBytes));
//                            }
//                        })
//                        .thenReturn(onlineMessage);
//            }
//            if (messageType.equals(org.jetlinks.demo.protocol.siterwell.tcp.MessageType.PING)) {
//
//                byte[] responseBytes = new S2DPong().toBytes();
//                return session
//                        .send(EncodedMessage.simple(Unpooled.wrappedBuffer(responseBytes)))
//                        .doOnNext(success -> {
//                            if (log.isDebugEnabled()) {
//                                log.debug("reply ping tcp message:\n{}", ByteUtils.byte2HexStr(responseBytes));
//                            }
//                        }).then(Mono.empty());
//            }
//            return Mono.empty();

        });
    }

    public String buildDeviceId(long deviceId) {
        return String.valueOf(deviceId);
    }

    /**
     * demo tcp 报文协议格式
     * <p>
     * 第0字节为消息类型
     * 第1-4字节为消息体长度
     * 第5-n为消息体
     */
    @Override
    public Publisher<? extends EncodedMessage> encode(MessageEncodeContext context) {
        Message message = context.getMessage();

        log.info("推送设备消息，消息ID：{}", message.getMessageId());
        ToDeviceMessageContext ctx = ((ToDeviceMessageContext) context);
        DeviceSession session = ctx.getSession();
        return pushMessage(session, message);
//        EncodedMessage encodedMessage = null;
//        // 获取设备属性
//        if (message instanceof ReadPropertyMessage) {
//            ReadPropertyMessage readPropertyMessage = (ReadPropertyMessage) message;
//            DemoTcpMessage of = DemoTcpMessage.of(MessageType.READ_PROPERTY, ReadProperty.of(readPropertyMessage));
//            encodedMessage = EncodedMessage.simple(of.toByteBuf());
//        }
//        //修改设备属性
//        if (message instanceof WritePropertyMessage) {
//            WritePropertyMessage writePropertyMessage = (WritePropertyMessage) message;
//            DemoTcpMessage of = DemoTcpMessage.of(MessageType.WRITE_PROPERTY, WriteProperty.of(writePropertyMessage));
//            encodedMessage = EncodedMessage.simple(of.toByteBuf());
//        }
//        // 设备上报属性
//        if (message instanceof ReportPropertyMessage) {
//            ReportPropertyMessage reportPropertyMessage = (ReportPropertyMessage) message;
//            DemoTcpMessage of = DemoTcpMessage.of(MessageType.REPORT_TEMPERATURE, ReportProperty.of(reportPropertyMessage));
//            encodedMessage = EncodedMessage.simple(of.toByteBuf());
//        }
//        return encodedMessage != null ? Mono.just(encodedMessage) : Mono.empty();
    }


}
